/* See the files LICENSE and COPYRIGHT for license and copyright information */
package org.rubiq;

/**
 * @author <a href="mailto:ola.bini@gmail.com">Ola Bini</a>
 */
public class LispCons extends LispExpression {
    private LispExpression car;
    private LispExpression cdr;

    public static LispCons list(LispExpression one) {
        return new LispCons(one);
    }

    public static LispCons list(LispExpression one, LispExpression two) {
        return new LispCons(one, new LispCons(two));
    }

    public static LispCons list(LispExpression one, LispExpression two, LispExpression three) {
        return new LispCons(one, new LispCons(two, new LispCons(three)));
    }

    public LispCons(LispExpression car) {
        this(car, new LispNil());
    }

    public LispCons(LispExpression car, LispExpression cdr) {
        this.car = car;
        this.cdr = cdr;
    }

    public LispExpression car() {
        return car;
    }

    public LispExpression cdr() {
        return cdr;
    }
    
    public LispCons append(LispExpression exp) {
        this.cdr = new LispCons(exp);
        return (LispCons)this.cdr;
    }

    protected void toString(StringBuffer sb) {
        if(car instanceof LispCons) {
            sb.append(car.toString());
        } else {
            car.toString(sb);
        }
        if(!(cdr instanceof LispNil)) {
            sb.append(" ");
            if(cdr instanceof LispCons) {
                cdr.toString(sb);
            } else {
                sb.append(". ");
                cdr.toString(sb);
            }
        }
    }

    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append('(');
        toString(sb);
        sb.append(')');
        return sb.toString();
    }
}// LispCons
